﻿
/*
EC-IDE class, from dom.Base template,
	SyntaxEditorEx
	org.supertree.editor.SyntaxEditorEx

Author: Feng Weiguo ( 冯卫国 )
Mail: forxm@21cn.com
Web: www.supertree.org

All Rights Reserved

LICENSE: LGPL

Created: 2008-12-03 14:52:24

Updated: 2008-12-10

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (LGPL) as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
*/

//#EC_PARAM $org.supertree.editor.SyntaxEditor

$ec.$preload(
	"org.supertree.editor.SyntaxEditorEx",
	function()
	{
		this.prototype=$ec.$derive(
			"org.supertree.editor.SyntaxEditor",
			{
//////////////////////////////
// EC-CLASS BODY
//////////////////////////////
			
			eidTool: "",	//eid for toolbar
			eidPos: "",		//eid for position report
			eidMenu: "",		//eid for menu
			eidInsertMenu: "",		//eid for insert menu
			eidContextMenu: "",		//eid for context menu
			eidFind: "",		//eid for find popup
			
			sSaveEval: "",		//eval() string for save
			sOpenEval: "",		//eval() string for open
			
			SyntaxEditorEx: function( e, p )	//ec-class constructor
			{
			},
			
			//SetOpen: function( [sOpenEval] )
			SetOpen: function( sOpenEval )
			{
				if( !this.eidTool ) throw "toolbar didn't prepare";
				
				var eiTool= $ec(this.eidTool);
				var ei= $ec( eiTool, "open" );
				if( !ei )
				{
					//create it
					ei= $ec(eiTool,"save");
					if( !ei )
					{
						ei= $ec(eiTool,"cut");
						
						//splitter
						if( $ec( ei,"p::<span>") ) ei= $ec( ei,"p::<span>");
						else ei= $ec(eiTool).CreateItem( 0, "", "", ei );	//splitter
					}
					
					$ec(eiTool).CreateItem( 1, "open", "Open", ei );
				}
				this.sOpenEval=sOpenEval;
			},
			
			//SetSave: function( [sSaveEval] )
			SetSave: function( sSaveEval )
			{
				if( !this.eidTool ) throw "toolbar didn't prepare";
				
				var eiTool= $ec(this.eidTool);
				var ei= $ec( eiTool, "save" );
				if( !ei )
				{
					ei= $ec(eiTool,"cut");
						
					//splitter
					if( $ec( ei,"p::<span>") ) ei= $ec( ei,"p::<span>");
					else ei= $ec(eiTool).CreateItem( 0, "", "", ei);	//splitter
					
					$ec(eiTool).CreateItem( 1, "save", "Save", ei );
				}
				this.sSaveEval=sSaveEval;
			},
			
			//CreateToolbar: function( eiTool [, bOpen [, bSave]] )
			CreateToolbar: function( eiTool, bOpen, bSave )
			{
				if( this.eidTool ) $ec.THROW("create toolbar more than once");
				
				if(!eiTool)
				{
					var e= $ec(this.eid);
					eiTool= e.parentNode.insertBefore( document.createElement("DIV"), e );
				}
				this.eidTool=$ec.$eid(eiTool);
				
				//eiTool.style.fontSize="5pt";
				
				$ec.$bind(
					"org.supertree.dom.Control.Toolbar",
					eiTool,
					{
						icon:$ec.$file['SyntaxEditor_gif'],
						height:15,
						data:[
							[2,'cut','Cut (Ctrl+X)'],
							[3,'copy','Copy (Ctrl+C)'],
							[4,'paste','Paste (Ctrl+V)'],
							[15,'delete','Delete (Del)'],
							"",
							[5,'undo','Undo (Ctrl+Z)'],
							[6,'redo','Redo (Ctrl+Y)'],
							"",
							[7,'find','Find/Replace (Ctrl+F)'],
							[8,'findnext','Find Next (F3)'],
							[9,'findprev','Find Previous (Shift+F3)'],
							[10,'bookmark','Toggle Bookmark (Ctrl+F2)'],
							[11,'nextmark','Next Bookmark (F2)'],
							[12,'prevmark','Previous Bookmark (Shift+F2)'],
							"",
							[14,'insertstring','Insert String'],
							[13,'menu','Menu/Tool']
							]
					}
					);
				//eiTool.style.lineHeight="5px";
				//eiTool.style.fontSize="5px";
				//eiTool.style.border="1px solid blue";
				
				//eiTool.style.position="relative";
				//eiTool.style.zIndex=10;
				//$ec(this.eid).style.zIndex=1;
				
				if(this.sAgent=="ie") eiTool.style.height="15px";	//ie bug??
				
				//alert(eiTool.outerHTML);
				
				var ei= eiTool.appendChild( document.createElement("SPAN") );
				ei.setAttribute( "name", "pos" );
				ei.style.fontSize="9pt";
				ei.style.color="gray";
				ei.style.paddingLeft="2em";
				this.eidPos= $ec.$eid(ei);
				
				//event
				$ec.addEvt(eiTool,this.eid,["","click","OnToolbarClick"]);
				
				if( bSave ) this.SetSave("");
				if( bOpen ) this.SetOpen("");
				
				return eiTool;
			},
			
			OnToolbarClick: function(evt)
			{
				var e= evt.srcElement?evt.srcElement:evt.target;
				if(!e) return;
				
				if( e.parentNode.id!=this.eidTool ) e=e.parentNode;	//for safari/chrome
				if( e.parentNode.id!=this.eidTool ) return;
				
				var cmd=e.getAttribute?e.getAttribute("name"):"";
				//alert(cmd);
				if(!cmd) return;
				
				if( ! this.OnCommand(cmd) ) return;
			},
			
			//overridable
			//if preocess the command, return true, else return false.
			//OnCommand: function( cmd [, param] )
			OnCommand: function( cmd )
			{
				switch(cmd)
				{
					case "open":
						if(this.sOpenEval) window.eval(this.sOpenEval);
						break;
					case "save":
						if(this.sSaveEval) window.eval(this.sSaveEval);
						break;
					case "cut":
						this.HideMenu();
						this.CutData();
						break;
					case "copy":
						this.HideMenu();
						this.CopyData();
						break;
					case "copyhypertext":
						this.HideMenu();
						this.CopyHyperText();
						break;
					case "textlength":
						this.HideMenu();
						alert("~ " + this.GetText().length + " Chars");
						break;
					case "paste":
						this.HideMenu();
						this.PasteData();
						break;
					case "delete":
						this.DeleteBlock();
						break;
					case "selectall":
						this.SelectAll();
						break;
					case "undo":
						this.Undo();
						break;
					case "redo":
						this.Redo();
						break;
					case "find":
						this.HideMenu();
						this.OnFind();
						break;
					case "findnext":
						this.FindNext();
						break;
					case "findprev":
						this.FindNext(1);
						break;
					case "bookmark":
						this.ToggleBookmark();
						break;
					case "nextmark":
						this.NextBookmark();
						break;
					case "prevmark":
						this.NextBookmark(1);
						break;
					case "menu":
						this.ShowToolMenu();
						break;
					case "insertstring":
						this.ShowInsertMenu();
						break;
					case "jump":
						this.HideMenu();
						this.OnJumpLine();
						break;
					case "overwrite":
						//this.HideMenu();
						//alert("h");
						//$ec.CALLSTACK();
						this.ToggleOverwrite();
						break;
					case "linenum":
						this.ToggleLineNumber();
						break;
					case "linebreak":
						this.ToggleLineBreak();
						break;
					case "font16":
						this.SetFontSize(16);
						break;
					case "font14":
						this.SetFontSize(14);
						break;
					case "font12":
						this.SetFontSize(12);
						break;
					case "nobold":
						this.ToggleNoBold();
						break;
					case "wrap":
						this.ToggleWrap();
						break;
					case "debug":
						this.ToggleDebugMode();
						break;
					case "help":
						this.HideMenu();
						this.ShowHelp();
						break;
					case "about":
						this.HideMenu();
						this.ShowAbout();
						break;
					case "stack":
						this.HideMenu();
						alert(this._line().getAttribute("Stack").substring(0,1000));
						break;
					case "timelocal":
					case "timeutc":
					case "timestamp":
					case "timestamp2":
					case "timelocaldate":
					case "timelocaltime":
					case "timeshortdate":
						this.InsertString( this.GetTimeString( new Date, cmd ) )
						break;
					default:
						if( cmd.substring(0,5)=="rule_" )
						{
							//alert( cmd.slice(5) );
							this.SetRule( parseInt(cmd.slice(5)) );
							break;
						}
						else if( cmd.substring(0,7)=="insert_" )
						{
							this.InsertText( this.oRule.aInsert[parseInt(cmd.slice(7))+1 ] );
							break;
						}
						else if( cmd.substring(0,5)=="user_" )
						{
							$ec.$notify(this,"usercmd",{cmd:cmd});
							break;
						}
						
						return false
						break;
				}
				return true;
			},
			
			nRuleCount:	1,
			nCurRule: 0,	//current rule index
			
			ShowToolMenu: function()
			{
				var eiTool= $ec(this.eidTool);
				var eiMenu= $ec(this.eidMenu);
				
				if( !eiMenu )
				{
					//create
					eiMenu= eiTool.insertBefore( document.createElement("DIV"), $ec(eiTool,"pos") );
					eiMenu.style.fontSize="9pt";
					eiMenu.style.fontFamily="'宋体','Courier New'";
					
					this.eidMenu= $ec.$eid(eiMenu);
					$ec.$bind(
						"org.supertree.dom.Popup.PopupMenu",
						eiMenu,
						{
							data:[
								{name:'rule',text:'Syntax Rule',
									data:[
										{name:'rule_0',text:'<nobr>Text</nobr>'}
										]
									},
								{name:'jump',text:'Jump... (Ctrl+G)'},
								{name:'copyhypertext',text:'Copy Hypertext'},
								{name:'textlength',text:'Text Length'},
								//{name:'overwrite',text:'<nobr>Toggle Overwrite (Insert)</nobr>'},
								{name:"-"},
								{name:'',text:'Font',
									data:[
										{name:'font16',text:'Font Size 16px'},
										{name:'font14',text:'Font Size 14px'},
										{name:'font12',text:'Font Size 12px'},
										{name:"-"},
										{name:'nobold',text:'<nobr>Toggle Bold Font</nobr>'}
										]
									},
								{name:'linenum',text:'Toggle Line Numer'},
								{name:'linebreak',text:'Toggle Line Break'},
								{name:'wrap',text:'Toggle Wrap/readonly'},
								{name:"-"},
								{name:'',text:'Developer',
									data: [
										{name:'stack',text:'Check Stack'},
										{name:'debug',text:'<nobr>Toggle Debug Mode</nobr>'}
										]
									},
								{name:"-"},
								{name:'help',text:'Help'},
								{name:'about',text:'About'}
								
								]
						}
						);
					
					//eiMenu.style.zIndex=15;
					
					//event
					$ec.addEvt(eiMenu,this.eid,["","click","OnMenuClick"]);
					
					//for Safari/Chrome, otherwise the menu will linebreak the toolbar at 1st time popup.
					$ec(eiMenu).GlobalPopup();
					$ec(eiMenu).HideGlobalPopup();
					window.setTimeout( "$ec.bind['"+this.eid+"'].ShowToolMenu()",0);
					return;
				}

				$ec(eiMenu).GlobalPopup();
				
				var ei= $ec(eiTool,"menu");
				var xy=this.getAbsXY(ei);
				//ei.style.position="relative";
				
				this.adjustStyleXY( eiMenu );
				var xy2=this.getAbsXY(eiMenu);
				
				eiMenu.style.left= (parseInt(eiMenu.style.left)+xy[0]-xy2[0])+"px";
				eiMenu.style.top= (parseInt(eiMenu.style.top)+xy[1]-xy2[1]+ei.offsetHeight)+"px";
				
				//rule list
				if( this.aRule.length>this.nRuleCount )
				{
					ei= $ec( eiMenu,"rule");
					$ec(eiMenu).showPopup(ei);	//pre-create popup
					var oRule= $ec($ec.$(ei,"<DIV>"));
					
					ei= $ec( ei,"rule_0").parentNode;
					var i,imax= this.aRule.length;
					for(i=this.nRuleCount;i<imax;i++)
					{
						oRule.addItem( ei, {name:"rule_"+i, text: "<nobr>"+this.aRule[i][1] +"</nobr>"} );
					}
					
					this.nRuleCount= this.aRule.length;
					
					$ec(eiMenu).ClearSelected();
				}
				
				//rule name
				if( this.nCurRule!=this.nRuleIdx )
				{
					ei= $ec( eiMenu,"rule.rule_"+this.nCurRule);
					ei= $ec.$(ei,"d::<nobr>");
					ei.innerHTML= this.getTextContent(ei);
					
					ei= $ec( eiMenu,"rule.rule_"+this.nRuleIdx);
					ei= $ec.$(ei,"d::<nobr>");
					ei.innerHTML= "<b>"+this.getTextContent(ei)+"</b>";
					
					this.nCurRule= this.nRuleIdx;
				}
				
			},
			
			HideMenu: function()
			{
				if(this.eidMenu) $ec.bind[this.eidMenu].HideGlobalPopup();
				if(this.eidInsertMenu) $ec.bind[this.eidInsertMenu].HideGlobalPopup();
				if(this.eidContextMenu) $ec.bind[this.eidContextMenu].HideGlobalPopup();
			},
			
			OnMenuClick: function(evt)
			{
				var e= evt.srcElement?evt.srcElement:evt.target;
				//$ec.TRACE(e.tagName+","+e.id);
				
				var cls= $ec.$import("org.supertree.dom.Popup.PopupMenu").prototype;
				e= cls.getMenuContainer(e);
				
				if(!e) return;
				
				var cmd=e.getAttribute?e.getAttribute("name"):"";
				if(!cmd) return;
				
				if( ! this.OnCommand(cmd) ) return;
				
				//hide menu
				this.HideMenu();
			},
			
			GetTimeString: function(dt, sType)
			{
				switch(sType)
				{
					case "timelocal": return dt.toLocaleString();
					case "timelocaldate": return dt.toLocaleDateString();
					case "timelocaltime": return dt.toLocaleTimeString();
					case "timeshortdate": return dt.getFullYear()+"-"+(dt.getMonth()+1)+"-"+dt.getDate();
					case "timeutc": return dt.toString();
					
					case "timestamp":
						var tz=-dt.getTimezoneOffset();
						if(tz!=0) tz=((tz<0)?"":"+")+Math.floor(tz/60)+":"+(tz%60);
						else tz="";
						return (dt.getFullYear()+"-"+(dt.getMonth()+1)+"-"+dt.getDate()+" "+dt.getHours()+":"+dt.getMinutes()+":"+dt.getSeconds()+" UTC"+tz).replace( /\b(\d)\b/g , "0$1");
					case "timestamp2":
						return (dt.getFullYear()+"-"+(dt.getMonth()+1)+"-"+dt.getDate()+" "+dt.getHours()+":"+dt.getMinutes()+":"+dt.getSeconds()).replace( /\b(\d)\b/g , "0$1");
					
					default: return ""+dt;
				}
			},
			
			nCurRuleInsert: 0,	//current rule insert string
			
			ShowInsertMenu: function()
			{
				var eiTool= $ec(this.eidTool);
				var eiMenu= $ec(this.eidInsertMenu);
				
				if( !eiMenu )
				{
					//create
					eiMenu= eiTool.insertBefore( document.createElement("DIV"), $ec(eiTool,"menu") );
					eiMenu.style.fontSize="9pt";
					
					this.eidInsertMenu= $ec.$eid(eiMenu);
					$ec.$bind(
						"org.supertree.dom.Popup.PopupMenu",
						eiMenu,
						{
							data:[
								{name:'inserttime',text:'Time',
									data:[
										{name:'timelocal',text:'Local'},
										{name:'timestamp2',text:'Timestamp2'},
										{name:'timeutc',text:'UTC'},
										{name:'timestamp',text:'Timestamp'},
										{name:"-"},
										{name:'timelocaldate',text:'Local Date'},
										{name:'timeshortdate',text:'Short Date'},
										{name:'timelocaltime',text:'Local Time'}
										]
									}
								]
						}
						);
					
					eiMenu.style.fontFamily="'宋体','Courier New'";
					
					//event
					$ec.addEvt(eiMenu,this.eid,["","click","OnMenuClick"]);
					
					//for Safari/Chrome, otherwise the menu will linebreak the toolbar at 1st time popup.
					$ec(eiMenu).GlobalPopup();
					$ec(eiMenu).HideGlobalPopup();
					window.setTimeout( "$ec.bind['"+this.eid+"'].ShowInsertMenu()",0);
					return;
				}

				$ec(eiMenu).GlobalPopup();
				
				var ei= $ec(eiTool,"insertstring");
				var xy=this.getAbsXY(ei);
				//ei.style.position="relative";
				
				this.adjustStyleXY( eiMenu );
				var xy2=this.getAbsXY(eiMenu);
				
				eiMenu.style.left= (parseInt(eiMenu.style.left)+xy[0]-xy2[0])+"px";
				eiMenu.style.top= (parseInt(eiMenu.style.top)+xy[1]-xy2[1]+ei.offsetHeight)+"px";
				
				//update time
				var dt= new Date;
				ei= $ec( eiMenu,"inserttime");
				$ec(eiMenu).showPopup(ei);	//pre-create popup
				/*
				if( !$ec.$(ei,"<DIV>" ) )
				{
					var ep= $ec.$(ei,"<DIV>" );
					$ec(ep).hidePopup(ep);
				}
				*/
				var es= $ec(ei,"timelocal");
				es.innerHTML="<nobr>"+this.GetTimeString( dt, "timelocal" )+"</nobr>";
				es= $ec(ei,"timestamp2",es);
				es.innerHTML="<nobr>"+this.GetTimeString( dt, "timestamp2" )+"</nobr>";
				es= $ec(ei,"timeutc",es);
				es.innerHTML="<nobr>"+this.GetTimeString( dt, "timeutc" )+"</nobr>";
				es= $ec(ei,"timestamp",es);
				es.innerHTML="<nobr>"+this.GetTimeString( dt, "timestamp" )+"</nobr>";
				
				es= $ec(ei,"timelocaldate",es);
				es.innerHTML="<nobr>"+this.GetTimeString( dt, "timelocaldate" )+"</nobr>";
				es= $ec(ei,"timeshortdate",es);
				es.innerHTML="<nobr>"+this.GetTimeString( dt, "timeshortdate" )+"</nobr>";
				es= $ec(ei,"timelocaltime",es);
				es.innerHTML="<nobr>"+this.GetTimeString( dt, "timelocaltime" )+"</nobr>";
				
				$ec(eiMenu).ClearSelected();
				
				//update insert string
				if(this.nCurRuleInsert!= this.nRuleIdx )
				{
					ei= $ec( eiMenu,"inserttime");
					while( ei.nextSibling ) ei.parentNode.removeChild(ei.nextSibling);
					
					if( this.oRule.aInsert )
					{
						//alert("h");
						var oMenu= $ec(eiMenu);
						
						ei=ei.parentNode;
						var i,imax= this.oRule.aInsert.length;
						//alert(this.oRule.aInsert.length);
						
						if(imax>0) oMenu.addItem(  ei, {name:"-"} );
						
						for(i=0;i<imax;i+=2)
						{
							es= oMenu.addItem(  ei, {name:"insert_"+i, text:this.oRule.aInsert[i] } );
						}
					}
					
					this.nCurRuleInsert= this.nRuleIdx;
				}
			},
			
			OnContextMenu: function(evt,clientX,clientY)
			{
				var eiTool= $ec(this.eidTool);
				var eiMenu= $ec(this.eidContextMenu);
				
				if(evt)
				{
					clientX= evt.clientX;
					clientY= evt.clientY;
				}
				
				if( !eiMenu )
				{
					//create
					eiMenu= eiTool.insertBefore( document.createElement("DIV"), $ec(eiTool,"pos") );
					eiMenu.style.fontSize="9pt";
					
					this.eidContextMenu= $ec.$eid(eiMenu);
					$ec.$bind(
						"org.supertree.dom.Popup.PopupMenu",
						eiMenu,
						{
							data:[
								{name:'cut',text:'Cut'},
								{name:'copy',text:'Copy'},
								{name:'paste',text:'Paste'},
								{name:'delete',text:'Delete'},
								{name:'-'},
								{name:'selectall',text:'Select All'},
								{name:'jump',text:'Jump...'}
								]
						}
						);
					
					eiMenu.style.fontFamily="'宋体','Courier New'";
					
					//event
					$ec.addEvt(eiMenu,this.eid,["","click","OnMenuClick"]);
					
					//for Safari/Chrome, otherwise the menu will linebreak the toolbar at 1st time popup.
					var oMenu= $ec(eiMenu);
					oMenu.GlobalPopup();
					oMenu.HideGlobalPopup();
					
					if( !window.clipboardData )
					{
						oMenu.EnableMenuItem("cut", false);
						oMenu.EnableMenuItem("copy", false);
						oMenu.EnableMenuItem("paste", false);
					}
					
					window.setTimeout( "$ec.bind['"+this.eid+"'].OnContextMenu(null,"+clientX+","+clientY+")",0);
					return evt?this.OnPreventEvent(evt):null;
				}

				$ec(eiMenu).GlobalPopup();
				
				var oMenu= $ec(eiMenu);
				if( window.clipboardData )
				{
					oMenu.EnableMenuItem("cut", (this.pos2[0]==-1 )?false:true);
					oMenu.EnableMenuItem("copy", (this.pos2[0]==-1 )?false:true);
				}
				oMenu.EnableMenuItem("delete", (this.pos2[0]==-1 )?false:true);
				
				this.adjustStyleXY( eiMenu );
				var xy2=this.getAbsXY(eiMenu);
				
				eiMenu.style.left= (parseInt(eiMenu.style.left)+clientX-xy2[0])+"px";
				eiMenu.style.top= (parseInt(eiMenu.style.top)+clientY-xy2[1])+"px";
				
				return evt?this.OnPreventEvent(evt):null;
			},
			
			//overridable function on mouse down
			CanFocus: function(evt)
			{
				if( this.eidFind )
				{
					var eEvt= evt.srcElement?evt.srcElement:evt.target;
					if( this.isAncestor( $ec(this.eidFind), eEvt) || eEvt.id==this.eidFind )
					{
						//$ec.TRACE("CanFocus false");
						return false;
					}
				}
				
				//$ec.TRACE("CanFocus true");
				return true;
			},
			
			OnFindCloseClick: function(evt)
			{
				var eiFind= $ec(this.eidFind);
				eiFind.style.display="none";
			},
			OnFindBackClick: function(evt)
			{
				var eiFind= $ec(this.eidFind);
				var ei= $ec(eiFind,"sFind");
				if(ei.value) this.FindString( ei.value, $ec(eiFind,"bCase").checked, 1 );
			},
			OnFindFindClick: function(evt)
			{
				var eiFind= $ec(this.eidFind);
				var ei= $ec(eiFind,"sFind");
				if(ei.value) this.FindString( ei.value, $ec(eiFind,"bCase").checked, 0 );
			},
			OnFindReplaceClick: function(evt)
			{
				var eiFind= $ec(this.eidFind);
				var ei= $ec(eiFind,"sFind");
				if(ei.value)
				{
					var bCase= $ec(eiFind,"bCase").checked;
					var sChk= this.GetBlockString([]).join("\n");
					
					if( (bCase && sChk==ei.value) || (!bCase && sChk.toLowerCase()==ei.value.toLowerCase() ) )
					{
						var s= $ec(eiFind,"sReplace").value;
						if(s)
						{
							this.InsertString(s);
						}
						else
						{
							this.DeleteBlock();
						}
					}
					
					this.FindString( ei.value, bCase, 0 );
				}
			},
			
			OnFindInputClick: function(evt)
			{
				/*
				//fix firefox, -- didn't work
				var z0= $ec(this.eid).style.zIndex;
				$ec(this.eid).style.zIndex = -1;
				window.setTimeout( "$ec('"+this.eid+"').style.zIndex=0",0 );
				*/
				var eEvt= evt.srcElement?evt.srcElement:evt.target;
				eEvt.select();
				eEvt.focus();
			},
			
			//override OnFind
			OnFind: function()
			{
				var eiTool= $ec(this.eidTool);
				var eiFind= $ec(this.eidFind);
				
				if( !eiFind )
				{
					//create
					eiFind= eiTool.insertBefore( document.createElement("DIV"), $ec(eiTool,"pos") );
					/*
					var e= $ec(this.eid);
					if(e.nextSibling )
					{
						eiFind= e.parentNode.insertBefore( document.createElement("DIV"), e.nextSibling );
					}
					else
					{
						eiFind= e.parentNode.appendChild( document.createElement("DIV") );
					}
					*/

					
					this.eidFind= $ec.$eid(eiFind);
					
					eiFind.style.position="absolute";
					eiFind.style.display="block";
					eiFind.style.width="240px";
					eiFind.style.height="130px";
					eiFind.style.zIndex=15;
					
					eiFind.innerHTML=$ec.$res["htmi_TextEditorFind"][0];
					$ec.$bind(eiFind);
					
					$ec($ec(eiFind,"title") ).BindDragable(eiFind);
					
					this.adjustStyleXY( eiFind );
					eiFind.style.top= (parseInt(eiFind.style.top)+ eiTool.offsetHeight)+"px";
					
					//event
					$ec.addEvt($ec(eiFind,"btnFindBack"),this.eid,["","click","OnFindBackClick"]);
					$ec.addEvt($ec(eiFind,"btnFind"),this.eid,["","click","OnFindFindClick"]);
					$ec.addEvt($ec(eiFind,"btnReplace"),this.eid,["","click","OnFindReplaceClick"]);
					$ec.addEvt($ec(eiFind,"btnClose"),this.eid,["","click","OnFindCloseClick"]);
					
					//firefox 2 bugs: 1. caret disappear, 2: designMode=off
					if(this.sAgent=="firefox") $ec.addEvt($ec(eiFind,"sFind"),this.eid,["","click","OnFindInputClick"]);
					
					$ec(eiFind,"sFind").readOnly=false;
					
					this.OnFindCloseClick();
					
					//for Safari/Chrome, otherwise the menu will linebreak the toolbar at 1st time popup.
					window.setTimeout( "$ec.bind['"+this.eid+"'].OnFind()",0);
					return;
				}
				eiFind.style.display="";
				
				var s= this.GetBlockString([]).join("\n");
				if( s) $ec(eiFind,"sFind").value = s;
				
			}
			
//////////////////////////////
// END EC-CLASS BODY	//NOTE - DO NOT CHANGE THESE 3 LINES, the ide wizards may use them.
//////////////////////////////
            }
		);
		
		//#EC_RES
		//#HTMI: htmi_TextEditorFind, Find.htmi
		//#FILE: {id:"SyntaxEditor_gif",path:"SyntaxEditor.gif",dyna:1}
		//#END_EC_RES
		
		//#EC_MAP
		this.$map=[
			["","contextmenu","OnContextMenu",1]
			];
		//#END_EC_MAP
		
	}
);
